#include "face_library_import.h"

int main(int argc, char *argv[]) 
{
  rockx_ret_t ret;
  rockx_image_t input_image;
  rockx_face_feature_t out_feature;
  const char *name = argv[1];
  const char *image_path = argv[2]; 
  
  char *rockx_data="/demo/src/rockx_data";
 
  if (argc != 3) 
  {
    printf("Usage: ./import_face_library  id face_name face_path\n");
    return -1;
  }

  open_db();

  rockx_config_t *config = rockx_create_config();
  rockx_add_config(config, ROCKX_CONFIG_DATA_PATH, rockx_data);

  // create a face detection handle
  ret = rockx_create(&face_det_handle, ROCKX_MODULE_FACE_DETECTION, config, 0);
  if (ret != ROCKX_RET_SUCCESS) 
  {
    printf("ERROR: init rockx module ROCKX_MODULE_FACE_DETECTION error %d\n", ret);
    return -1;
  }

  // create a face landmark handle
  ret = rockx_create(&face_5landmarks_handle, ROCKX_MODULE_FACE_LANDMARK_5,config, 0);
  if (ret != ROCKX_RET_SUCCESS) 
  {
    printf("ERROR: init rockx module ROCKX_MODULE_FACE_LANDMARK_68 error %d\n", ret);
    return -1;
  }

  // create a face recognize handle
  ret = rockx_create(&face_recognize_handle, ROCKX_MODULE_FACE_RECOGNIZE,config, 0);
  if (ret != ROCKX_RET_SUCCESS) 
  {
    printf("ERROR: init rockx module ROCKX_MODULE_FACE_LANDMARK_68 error %d\n", ret);
    return -1;
  }

  rockx_image_read(image_path, &input_image, 1);
  run_face_recognize(name, &input_image, &out_feature);

  return 0;
}


rockx_object_t *get_max_face(rockx_object_array_t *face_array) 
{
  int i;
  rockx_object_t *max_face = NULL;

  if (face_array->count == 0) 
  {
    return NULL;
  }
  
  for (i = 0; i < face_array->count; i++) 
  {
    rockx_object_t *cur_face = &(face_array->object[i]);
    if (max_face == NULL) 
    {
      max_face = cur_face;
      continue;
    }
    int cur_face_box_area = (cur_face->box.right - cur_face->box.left) *
                            (cur_face->box.bottom - cur_face->box.top);
    int max_face_box_area = (max_face->box.right - max_face->box.left) *
                            (max_face->box.bottom - max_face->box.top);
    if (cur_face_box_area > max_face_box_area) 
    {
      max_face = cur_face;
    }
  }
  printf("get_max_face %d\n", i);
  return max_face;
}


int run_face_recognize(const char *name, rockx_image_t *in_image, rockx_face_feature_t *out_feature) 
{
  rockx_ret_t ret;
  rockx_object_array_t face_array;
  memset(&face_array, 0, sizeof(rockx_object_array_t));
  ret = rockx_face_detect(face_det_handle, in_image, &face_array, nullptr);
  if (ret != ROCKX_RET_SUCCESS) 
  {
    printf("ERROR: rockx_face_detect error %d\n", ret);
    return -1;
  }

  for (int i = 0; i < face_array.count; i++) 
  {
    int left = face_array.object[i].box.left;
    int top = face_array.object[i].box.top;
    int right = face_array.object[i].box.right;
    int bottom = face_array.object[i].box.bottom;
    float score = face_array.object[i].score;
    printf("box=(left,top,right,bottom)=(%d %d %d %d)\n", left, top, right, bottom);
    int w = face_array.object[i].box.right - face_array.object[i].box.left;
    int h = face_array.object[i].box.bottom - face_array.object[i].box.top;
    printf("w=right-left=%d\n", w);
    printf("h=right-left=%d\n", h);
    printf("score=%f\n\n", score);
  }

  int j;
  rockx_object_t *max_face = NULL;
  if (face_array.count == 0) 
  {
    return NULL;
  }
  
  for (j = 0; j < face_array.count; j++) 
  {
    rockx_object_t *cur_face = &(face_array.object[j]);
    if (max_face == NULL) 
    {
      max_face = cur_face;
      continue;
    }
    int cur_face_box_area = (cur_face->box.right - cur_face->box.left) *
                            (cur_face->box.bottom - cur_face->box.top);
    int max_face_box_area = (max_face->box.right - max_face->box.left) *
                            (max_face->box.bottom - max_face->box.top);
    if (cur_face_box_area > max_face_box_area) 
    {
      max_face = cur_face;
    }
  }
  printf("get_max_face %d\n", j);

  if (max_face == NULL) 
  {
    printf("ERROR: no face detected\n");
    return -1;
  }

  rockx_image_t out_img;
  memset(&out_img, 0, sizeof(rockx_image_t));
  ret = rockx_face_align(face_5landmarks_handle, in_image, &(max_face->box),NULL, &out_img);
  if (ret != ROCKX_RET_SUCCESS) 
  {
    printf("ERROR: rockx_face_align failed\n");
    return -1;
  }

  rockx_face_recognize(face_recognize_handle, &out_img, out_feature);

  insert_face_data_to_database(name, FEATURE_SIZE, out_feature->feature);

  rockx_image_release(&out_img);

  return 0;
}

